Skip to content

Sentinel soft-fail follow-ups: discovery failure as RedisConnectionException, late sentinel init, clear LastException - #3280

Merged
mgravell merged 1 commit into
mainfrom
marc/sentinel-soft-fail-followups
Oct 16, 2026
Merged

mgravell merged 1 commit into
mainfrom
marc/sentinel-soft-fail-followups

Conversation

@mgravell

Copy link
Copy Markdown
Collaborator

Follow-ups to #3187 (AbortOnConnectFail=false for sentinel), as promised in #3271. None of this changes behaviour for abortConnect=true.

Changes

  • Discovery failure surfaces as RedisConnectionException. GetSentinelMasterConnection with a config that has no endpoints of its own (the direct-API pattern: a long-lived SentinelConnect, then a per-service config carrying only ServiceName) threw AggregateException(InvalidOperationException("No nodes to consider")) from the seed connect when nothing was discovered. It now throws the discovery RedisConnectionException, as it did before Fix Sentinel connection leak and AbortOnConnectFail=false handling #3187. Measured against a live sentinel with an unknown service name.
  • Late sentinel initialisation. A sentinel connection whose initial connect soft-failed never ran InitializeSentinel, because only the connect paths call it. Such a connection recovered and followed failovers, but only via the fallback polling: it never subscribed to +switch-master. Measured: subscription absent after recovery. InitializeSentinel is now idempotent and is also reached from a non-first reconfigure that detects a sentinel. The first connect still leaves it to ConnectImpl, so the happy-path ordering is unchanged.
  • LastException cleared on recovery. The discovery failure recorded at connect time stayed in LastException after the connection reached its primary, and the exception factory folded it into every later "no connection available" message. Cleared in OnManagedConnectionRestored once the switch succeeds.
  • Docs. Configuration.md now says what abortConnect means for sentinel connections, and that abortConnect=true is the fail-fast setting.

Tests

  • New SentinelConfigTests.GetSentinelMasterConnection_NothingToSeedWith_AbortDisabled_ThrowsTheDiscoveryFailure (closed loopback port, no topology).
  • SentinelTests.AbortOnConnectFailFalseRecoversOnceSentinelsAppear additionally asserts the +switch-master subscription and a null LastException after recovery; both were false before this change.
  • All Sentinel* classes pass against a local primary/replica/three-sentinel topology (32 passed, 1 long-running skip). dotnet build Build.csproj -c Release /p:CI=true is clean. No public API changes.

…ception, late sentinel init, clear LastException

Follow-ups to #3187 (AbortOnConnectFail=false for sentinel), prompted by the
investigation of #3271:

- GetSentinelMasterConnection with a config that has no endpoints of its own
  and nothing discovered threw AggregateException(InvalidOperationException
  "No nodes to consider") from the seed connect. It now throws the discovery
  RedisConnectionException, as it did before #3187.
- A sentinel connection whose initial connect soft-failed never ran
  InitializeSentinel, because only the connect paths called it; such a
  connection never subscribed to +switch-master and tracked failovers only
  through the fallback polling. InitializeSentinel is now idempotent and is
  also reached from a non-first reconfigure that detects a sentinel.
- The discovery failure recorded as LastException at connect time stayed
  there after recovery and was folded into every later "no connection
  available" message. It is cleared once the managed connection is restored.
- Document what abortConnect means for sentinel connections.
@mgravell
mgravell merged commit 84765ee into main Oct 16, 2026
5 checks passed
@mgravell
mgravell deleted the marc/sentinel-soft-fail-followups branch October 16, 2026 09:44
FloatingMilkshake pushed a commit to FloatingMilkshake/MechanicalMilkshake that referenced this pull request Oct 24, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [StackExchange.Redis](https://seredis.dev/) ([source](https://github.com/StackExchange/StackExchange.Redis)) | nuget | patch | `3.4.0` → `3.4.20` |

---

### Release Notes

<details>
<summary>StackExchange/StackExchange.Redis (StackExchange.Redis)</summary>

### [`v3.4.20`](https://github.com/StackExchange/StackExchange.Redis/releases/tag/3.4.20)

[Compare Source](StackExchange/StackExchange.Redis@3.4.5...3.4.20)

#### Stability improvements

- Do not abandon a connection attempt before ConnectTimeout has elapsed by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3277](StackExchange/StackExchange.Redis#3277)
- Read HELLO "server" before trusting "version" as the Redis API version by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3279](StackExchange/StackExchange.Redis#3279)
- Sentinel soft-fail follow-ups: discovery failure as RedisConnectionException, late sentinel init, clear LastException by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3280](StackExchange/StackExchange.Redis#3280)
- Sentinel: re-resolve the primary when it is demoted on a healthy connection by [@&#8203;rebaseandpanic](https://github.com/rebaseandpanic) in [#&#8203;3281](StackExchange/StackExchange.Redis#3281)
- Route as a cluster only with a slot map; take HELLO mode/role from the interactive connection only by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3285](StackExchange/StackExchange.Redis#3285)
- Fail connection-dropped commands with RedisConnectionException, never a raw transport exception or a cancellation by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3287](StackExchange/StackExchange.Redis#3287)
- Connection groups: a member answering LOADING triggers an immediate re-probe and re-select by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3289](StackExchange/StackExchange.Redis#3289)
- IBatch: complete commands refused by a poisoned connection; divert a batch's tail on reconnect by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3286](StackExchange/StackExchange.Redis#3286)
- Give multi-message sub-commands and injected prefix commands a write time by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3293](StackExchange/StackExchange.Redis#3293)
- Send primary-only commands to the primary when the caller prefers a replica by [@&#8203;AsadIqbal-Dev](https://github.com/AsadIqbal-Dev) in [#&#8203;3291](StackExchange/StackExchange.Redis#3291)

#### Maintenance

- Tests: stabilise two recurring Windows CI flakes (hash-field expiry clock skew, backlog counter quiescence) by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3288](StackExchange/StackExchange.Redis#3288)
- Tests: don't race the connect's own reconfigures in AllClusterCommandsRefusedIsQuiet by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3290](StackExchange/StackExchange.Redis#3290)
- Refresh package pins: 10.0.13 servicing family and tooling by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3294](StackExchange/StackExchange.Redis#3294)
- xunit.v3 4.0 on Microsoft.Testing.Platform by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3295](StackExchange/StackExchange.Redis#3295)
- StyleCop.Analyzers 1.3.151-beta, and the tidy-up it asks for by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3296](StackExchange/StackExchange.Redis#3296)

#### New Contributors

- [@&#8203;AsadIqbal-Dev](https://github.com/AsadIqbal-Dev) made their first contribution in [#&#8203;3291](StackExchange/StackExchange.Redis#3291)

**Full Changelog**: <StackExchange/StackExchange.Redis@3.4.5...3.4.20>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xODEuMCIsInVwZGF0ZWRJblZlciI6IjQ0LjE4MS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://git.milkshake.services/FloatingMilkshake/MechanicalMilkshake/pulls/10
Reviewed-by: Milkshake <me@floatingmilkshake.com>
FloatingMilkshake pushed a commit to FloatingMilkshake/Azusa that referenced this pull request Oct 24, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [StackExchange.Redis](https://seredis.dev/) ([source](https://github.com/StackExchange/StackExchange.Redis)) | nuget | patch | `3.4.0` → `3.4.20` |

---

### Release Notes

<details>
<summary>StackExchange/StackExchange.Redis (StackExchange.Redis)</summary>

### [`v3.4.20`](https://github.com/StackExchange/StackExchange.Redis/releases/tag/3.4.20)

[Compare Source](StackExchange/StackExchange.Redis@3.4.5...3.4.20)

#### Stability improvements

- Do not abandon a connection attempt before ConnectTimeout has elapsed by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3277](StackExchange/StackExchange.Redis#3277)
- Read HELLO "server" before trusting "version" as the Redis API version by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3279](StackExchange/StackExchange.Redis#3279)
- Sentinel soft-fail follow-ups: discovery failure as RedisConnectionException, late sentinel init, clear LastException by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3280](StackExchange/StackExchange.Redis#3280)
- Sentinel: re-resolve the primary when it is demoted on a healthy connection by [@&#8203;rebaseandpanic](https://github.com/rebaseandpanic) in [#&#8203;3281](StackExchange/StackExchange.Redis#3281)
- Route as a cluster only with a slot map; take HELLO mode/role from the interactive connection only by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3285](StackExchange/StackExchange.Redis#3285)
- Fail connection-dropped commands with RedisConnectionException, never a raw transport exception or a cancellation by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3287](StackExchange/StackExchange.Redis#3287)
- Connection groups: a member answering LOADING triggers an immediate re-probe and re-select by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3289](StackExchange/StackExchange.Redis#3289)
- IBatch: complete commands refused by a poisoned connection; divert a batch's tail on reconnect by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3286](StackExchange/StackExchange.Redis#3286)
- Give multi-message sub-commands and injected prefix commands a write time by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3293](StackExchange/StackExchange.Redis#3293)
- Send primary-only commands to the primary when the caller prefers a replica by [@&#8203;AsadIqbal-Dev](https://github.com/AsadIqbal-Dev) in [#&#8203;3291](StackExchange/StackExchange.Redis#3291)

#### Maintenance

- Tests: stabilise two recurring Windows CI flakes (hash-field expiry clock skew, backlog counter quiescence) by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3288](StackExchange/StackExchange.Redis#3288)
- Tests: don't race the connect's own reconfigures in AllClusterCommandsRefusedIsQuiet by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3290](StackExchange/StackExchange.Redis#3290)
- Refresh package pins: 10.0.13 servicing family and tooling by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3294](StackExchange/StackExchange.Redis#3294)
- xunit.v3 4.0 on Microsoft.Testing.Platform by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3295](StackExchange/StackExchange.Redis#3295)
- StyleCop.Analyzers 1.3.151-beta, and the tidy-up it asks for by [@&#8203;mgravell](https://github.com/mgravell) in [#&#8203;3296](StackExchange/StackExchange.Redis#3296)

#### New Contributors

- [@&#8203;AsadIqbal-Dev](https://github.com/AsadIqbal-Dev) made their first contribution in [#&#8203;3291](StackExchange/StackExchange.Redis#3291)

**Full Changelog**: <StackExchange/StackExchange.Redis@3.4.5...3.4.20>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xODEuMCIsInVwZGF0ZWRJblZlciI6IjQ0LjE4MS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://git.milkshake.services/FloatingMilkshake/Azusa/pulls/10
Reviewed-by: Milkshake <me@floatingmilkshake.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant